﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Runtime.InteropServices;

namespace DCSoft.TemperatureChart
{
    /// <summary>
    /// Y坐标轴信息
    /// </summary>
    /// <remarks></remarks>
    [Serializable]
    [ComVisible(false)]
    public class YAxisInfo
    {
        /// <summary>
        /// 初始化对象
        /// </summary>
        public YAxisInfo()
        {
        }

        /// <summary>
        /// 初始化对象
        /// </summary>
        /// <param name="_title"></param>
        /// <param name="_valueMember"></param>
        /// <param name="_maxValue"></param>
        /// <param name="_minValue"></param>
        /// <param name="_symbolStyle"></param>
        /// <param name="_symbolColor"></param>
        public YAxisInfo(
            string _title,
            ValueMemberType _valueMember,
            float _maxValue, 
            float _minValue,
            PointSymbolStyle _symbolStyle ,
            Color _symbolColor )
        {
            this.Title = _title;
            this.ValueMember = _valueMember;
            this.MaxValue = _maxValue;
            this.MinValue = _minValue;
            this.SymbolStyle = _symbolStyle;
            this.SymbolColor = _symbolColor;
        }

        private string _Title = null;
        /// <summary>
        /// 标题
        /// </summary>
        [DefaultValue( null )]
        public string Title
        {
            get { return _Title; }
            set { _Title = value; }
        }

        private ValueMemberType _ValueMember = ValueMemberType.Body_Temperature ;
        /// <summary>
        /// 数据成员
        /// </summary>
        [DefaultValue( ValueMemberType.Body_Temperature )]
        public ValueMemberType ValueMember
        {
            get { return _ValueMember; }
            set { _ValueMember = value; }
        }

        private float _MaxValue = 0f;
        /// <summary>
        /// 最大值
        /// </summary>
        [DefaultValue( 0f )]
        public float MaxValue
        {
            get { return _MaxValue; }
            set { _MaxValue = value; }
        }

        private float _MinValue = 0;
        /// <summary>
        /// 最小值
        /// </summary>
        [DefaultValue( 0f)]
        public float MinValue
        {
            get { return _MinValue; }
            set { _MinValue = value; }
        }

        private PointSymbolStyle _SymbolStyle = PointSymbolStyle.SolidCicle;
        /// <summary>
        /// 数据点符号类型
        /// </summary>
        [DefaultValue( PointSymbolStyle.SolidCicle )]
        public PointSymbolStyle SymbolStyle
        {
            get { return _SymbolStyle; }
            set { _SymbolStyle = value; }
        }

        private Color _SymbolColor = Color.Red;
        /// <summary>
        /// 数据点符号颜色
        /// </summary>
        [XmlIgnore]
        public Color SymbolColor
        {
            get { return _SymbolColor; }
            set { _SymbolColor = value; }
        }

        /// <summary>
        /// 文本形式的颜色值
        /// </summary>
        [Browsable( false )]
        [XmlElement]
        [DefaultValue("Red")]
        public string SymbolColorValue
        {
            get
            {
                return ColorTranslator.ToHtml(this.SymbolColor);
            }
            set
            {
                this.SymbolColor = ColorTranslator.FromHtml(value);
            }
        }


        //private float _SymbolSize = 20;
        ///// <summary>
        ///// 数据点符号大小
        ///// </summary>
        //[DefaultValue( 20 )]
        //public float SymbolSize
        //{
        //    get { return _SymbolSize; }
        //    set { _SymbolSize = value; }
        //}

        /// <summary>
        /// Y坐标轴区域左边界位置
        /// </summary>
        [NonSerialized]
        internal float ViewLeft = 0f;
        /// <summary>
        /// Y坐标轴文本在视图中占据的宽度
        /// </summary>
        [NonSerialized]
        internal float ViewWidth = 0f;

        public float GetPosition(float maxPos, float minPos , float value )
        {
            if( float.IsNaN( value ))
            {
                return float.NaN ;
            }
            if (maxPos > minPos)
            {
                float rate = (maxPos - minPos) / (_MaxValue - _MinValue);
                return minPos + (value - _MinValue) * rate;
            }
            else
            {
                return maxPos;
            }
        }

        /// <summary>
        /// 上一次数据点
        /// </summary>
        [NonSerialized]
        internal PointF LastPoint = new PointF(float.NaN, float.NaN);
        
        internal float GetValue(Measure instance)
        {
            if (instance == null)
            {
                return float.NaN;
            }
            switch (this.ValueMember)
            {
                case ValueMemberType.Body_Temperature  :
                    return instance.Body_Temperature;
                case ValueMemberType.Breath :
                    return instance.Breath;
                case ValueMemberType.FT :
                    return instance.FT;
                case ValueMemberType.Pluse :
                    return instance.Pluse;
            }
            return float.NaN;
        }

    }

    /// <summary>
    /// Y坐标轴信息列表
    /// </summary>
    [Serializable]
    [ComVisible(false)]
    public class YAxisInfoList : List<YAxisInfo>
    {
        /// <summary>
        /// 初始化对象
        /// </summary>
        public YAxisInfoList()
        {
        }

        /// <summary>
        /// 获得指定数据类型的坐标轴信息
        /// </summary>
        /// <param name="type">指定的数据类型</param>
        /// <returns>获得的坐标轴信息</returns>
        public YAxisInfo GetItem(ValueMemberType type)
        {
            foreach (YAxisInfo info in this)
            {
                if (info.ValueMember == type)
                {
                    return info;
                }
            }
            return null;
        }

        /// <summary>
        /// 为取值范围而修正对象数值
        /// </summary>
        /// <param name="m">数据</param>
        /// <returns>操作是否修改了对象数据</returns>
        public bool FixRange(Measure m)
        {
            bool result = false;
            foreach (YAxisInfo info in this)
            {
                float v = info.GetValue( m );
                bool changed = false ;
                if( float.IsNaN( v ) == false )
                {
                    if( float.IsNaN( info.MaxValue ) == false 
                        && v >info.MaxValue )
                    {
                        v = info.MaxValue ;
                        changed = true ;
                    }
                    else if( float.IsNaN( info.MinValue ) == false 
                        && v < info.MinValue )
                    {
                        v = info.MinValue ;
                        changed = true ;
                    }
                    if( changed )
                    {
                        switch( info.ValueMember )
                        {
                            case  ValueMemberType.Body_Temperature :
                                result = true ;
                                m.Body_Temperature = v ;
                                break;
                            case  ValueMemberType.Breath :
                                result = true ;
                                m.Breath = v ;
                                break;
                            case ValueMemberType.FT :
                                result = true ;
                                m.FT = v ;
                                break;
                            case ValueMemberType.Pluse :
                                result = true ;
                                m.Pluse = v ;
                                break;
                        }
                    }
                }
            }
            return result;
        }

    }    
}
